/**
 * @name tcphdr flow to mbuf_copydata
 * @description Expressions of type tcphdr usually contain values that can
 *              be controlled by an attacker. Therefore, it is dangerous to
 *              use any of those values as the size argument of
 *              mbuf_copydata.
 * @kind path-problem
 * @problem.severity warning
 * @id apple-xnu/cpp/tcphdr_mbuf_copydata
 */

import cpp
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph

class Config extends TaintTracking::Configuration {
  Config() { this = "tcphdr_flow" }

  override predicate isSource(DataFlow::Node source) {
  	source.asExpr().getType().stripType().getName() = "tcphdr"
  }

  override predicate isSink(DataFlow::Node sink) {
  	exists (FunctionCall call
  	| call.getArgument(2) = sink.asExpr() and
  	  call.getTarget().getName() = "mbuf_copydata")
  }
}

from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "tcp"
